package com.road.yishi.conn;

import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.road.yishi.mina.LinkedClient;

/**
 * @Description :
 * @FileName: ClientTryer.java
 * @Author :WeiHui.Zhang
 * @Data : 2016年2月26日 下午7:09:17
 * @Version:V1.00
 */
public final class ClientTryer {

	private static final Logger LOGGER = LoggerFactory.getLogger(ClientTryer.class);

	private static final ClientTryer INSTANCE = new ClientTryer();

	private ScheduledThreadPoolExecutor executor;

	public static ClientTryer getInstance() {
		return INSTANCE;
	}

	private ClientTryer() {
		executor = new ScheduledThreadPoolExecutor(1);
	}

	/**
	 * 
	 * @Name: ctry
	 * @Description:每隔一段时间尝试连接一次
	 * @Author: WeiHui.Zhang
	 * @Version: V1.00
	 * @Date: 2016年2月26日下午7:12:26
	 * @param client
	 * @param period
	 * @param tryTimes
	 *            大于0，尝试次数，小于0 ，无限尝试
	 * @Return: void
	 */
	public void ctry(LinkedClient client, int period, int tryTimes) {
		TryRunner tryRunner = new TryRunner(client, tryTimes);
		ScheduledFuture<?> future = executor.scheduleAtFixedRate(tryRunner, period, period, TimeUnit.SECONDS);
		tryRunner.setFuture(future);
		tryRunner.setExecutor(executor);
	}

	private class TryRunner implements Runnable {

		private LinkedClient client;
		private int tryTimes;
		private ScheduledFuture<?> future;
		private ScheduledThreadPoolExecutor executor;

		public TryRunner(LinkedClient client, int tryTimes) {
			this.client = client;
			this.tryTimes = tryTimes;
		}

		@Override
		public void run() {
			if (tryTimes > 0) {
				tryTimes--;
			}
			if (!client.isTry()) {
				stopTry();
				LOGGER.info("Try connect to " + client.getAddress() + ":" + client.getPort() + " cancel, tryRunner will exit.");
				return;
			}

			boolean result = client.connect();
			if (result) {
				stopTry();
				LOGGER.info("Try connect to " + client.getAddress() + ":" + client.getPort() + " succeed,tryRunner exit.");
			} else if (tryTimes == 0) {
				stopTry();
				LOGGER.info("Try connect to " + client.getAddress() + " fail, tryRunner will exit.");
			}

		}

		public void setFuture(ScheduledFuture<?> future) {
			this.future = future;
		}

		public void setExecutor(ScheduledThreadPoolExecutor executor) {
			this.executor = executor;
		}

		private void stopTry() {
			future.cancel(true);
			executor.shutdown();
		}

	}

	public static void main(String[] args) {
		ClientTryer.getInstance().ctry(null, 1, 10);
	}

}
